module gray_cntr_fsm (clk, arst, count);
input        clk;    // clock signal (rise-edge)
input        arst;   // asynchronous reset
output [3:0] count;  // count output

// FSM states registers
reg [3:0] cur_state;
reg [3:0] nxt_state;

// FSM states encoding
parameter [3:0] S0 = 4'b0000,
                S1 = 4'b0001,
                S2 = 4'b0011,
                S3 = 4'b0010,
                S4 = 4'b0110,
                S5 = 4'b0111,
                S6 = 4'b0101,
                S7 = 4'b0100,
                S8 = 4'b1100,
                S9 = 4'b1101,
               S10 = 4'b1111,
               S11 = 4'b1110,
               S12 = 4'b1010,
               S13 = 4'b1011,
               S14 = 4'b1001,
               S15 = 4'b1000;

// FSM registered process
always@(posedge clk, posedge arst) begin
   if (arst)
      cur_state <= S0;
   else
      cur_state <= nxt_state;
end

// FSM combinational process
always@(*) begin
   case(cur_state)
       S0 : nxt_state = S1;
       S1 : nxt_state = S2;
       S2 : nxt_state = S3;
       S3 : nxt_state = S4;
       S4 : nxt_state = S5;
       S5 : nxt_state = S6;
       S6 : nxt_state = S7;
       S7 : nxt_state = S8;
       S8 : nxt_state = S9;
       S9 : nxt_state = S10;
      S10 : nxt_state = S11;
      S11 : nxt_state = S12;
      S12 : nxt_state = S13;
      S13 : nxt_state = S14;
      S14 : nxt_state = S15;
      S15 : nxt_state = S0;
	  default: nxt_state = S0;
   endcase
end

// output assignment
assign count = cur_state;

endmodule
